package stack

// https://leetcode.cn/problems/min-stack leetcode-155
type Element struct {
	next, prev *Element
	val        int
}

type MinStack struct {
	root *Element
	min  []int
}

func Constructor() MinStack {
	return MinStack{
		root: &Element{},
		min:  make([]int, 0),
	}
}

func (this *MinStack) Push(val int) {
	next := this.root.next
	e := &Element{val: val, next: next}
	this.root.next = e

	if next != nil {
		next.prev = e
	}

	if len(this.min) == 0 || val <= this.min[len(this.min)-1] {
		this.min = append(this.min, val)
	}
}

func (this *MinStack) Pop() {
	deleteNode := this.root.next
	if deleteNode == nil {
		return
	}
	this.root.next = deleteNode.next
	if this.root.next != nil {
		this.root.next.prev = nil
	}
	deleteNode.next = nil
	if deleteNode.val == this.GetMin() {
		this.min = this.min[:len(this.min)-1]
	}
}

func (this *MinStack) Top() int {
	return this.root.next.val
}

func (this *MinStack) GetMin() int {
	return this.min[len(this.min)-1]
}

/**
 * Your MinStack object will be instantiated and called as such:
 * obj := Constructor();
 * obj.Push(val);
 * obj.Pop();
 * param_3 := obj.Top();
 * param_4 := obj.GetMin();
 */
